/**
 * 第三步：组件选择组件
 * 包含基础组件选择和扩展组件（建议）选择
 */
import React, { useEffect, useMemo, useState } from 'react';
import { Form, Checkbox, Button, Modal, Typography, notification, message, Tag } from 'antd';
import { CopyOutlined } from '@ant-design/icons';
import { useSelector } from 'react-redux';
import { RootState } from '@/types';
import { BaseComponent } from '@/types/project';
import { FormInstance } from 'antd';

const { Text, Paragraph, Title } = Typography;

interface ComponentsSelectionStepProps {
  form: FormInstance;
  baseComponents: BaseComponent[];
}

interface RecommendationParams {
  uiFramework: string;
  language: string;
  buildTool: string;
  targetPlatform: string;
  requirementDescription: string;
}

// 组件内部根据用户输入的 projectName 动态构造框架创建命令
// 注意：需在组件内部调用 Form.useWatch

const ComponentsSelectionStep: React.FC<ComponentsSelectionStepProps> = ({ 
  form, baseComponents 
}) => {
  const [isModalVisible, setIsModalVisible] = useState(false);
  // 支持的框架类型
  type FrameworkType = 'react' | 'vue';
  // 用于存储当前项目创建命令
  const [selectedCommand, setSelectedCommand] = useState<{ command: string; officialName: string }>({ command: '', officialName: '' });

  const suggested = useSelector((state: RootState) => state.project.suggestedComponents);
  const selectedBaseComponents = Form.useWatch('baseComponents', form) || [];
  const selectedExtendedComponents = Form.useWatch('extendedComponents', form) || [];
  const uiFramework = Form.useWatch('uiFramework', form);
  const language = Form.useWatch('language', form);
  const buildTool = Form.useWatch('buildTool', form);
  const targetPlatform = Form.useWatch('targetPlatform', form);
  const requirementDescription = Form.useWatch('requirementDescription', form) || '';

  const [installCommand, setInstallCommand] = useState('');
  const [notified, setNotified] = useState(false);
  const [recommendationNotified, setRecommendationNotified] = useState(false);

  // 定义前几个组件为必需组件（比如前2个）
  const requiredComponentNames = useMemo(() => {
    const explicitRequired = baseComponents
      .filter(component => component.required)
      .map(component => component.name);

    if (explicitRequired.length > 0) {
      return explicitRequired;
    }

    return baseComponents.slice(0, 2).map(component => component.name);
  }, [baseComponents]);

  const recommendationParams = useMemo<RecommendationParams>(() => ({
    uiFramework: uiFramework || 'react',
    language: language || 'typescript',
    buildTool: buildTool || 'vite',
    targetPlatform: targetPlatform || 'pc',
    requirementDescription: requirementDescription || '',
  }), [uiFramework, language, buildTool, targetPlatform, requirementDescription]);

  const recommendationRules = useMemo(() => ([
    {
      match: (params: RecommendationParams) => params.uiFramework === 'react',
      components: ['react-router-dom', '@reduxjs/toolkit', 'react-redux', '@tanstack/react-query'],
    },
    {
      match: (params: RecommendationParams) => params.uiFramework === 'vue',
      components: ['vue-router', 'pinia', '@vueuse/core'],
    },
    {
      match: (params: RecommendationParams) => params.language === 'typescript',
      components: ['typescript', '@types/node'],
    },
    {
      match: (params: RecommendationParams) => params.buildTool === 'vite' && params.uiFramework === 'react',
      components: ['@vitejs/plugin-react'],
    },
    {
      match: (params: RecommendationParams) => params.buildTool === 'vite' && params.uiFramework === 'vue',
      components: ['@vitejs/plugin-vue'],
    },
    {
      match: (params: RecommendationParams) => params.targetPlatform === 'mobile',
      components: ['vant', '@vant/use'],
    },
    {
      match: (params: RecommendationParams) =>
        /国际化|i18n|多语言/i.test(params.requirementDescription),
      components: ['react-i18next', 'i18next', 'vue-i18n'],
    },
    {
      match: (params: RecommendationParams) =>
        /数据|接口|api|登录|认证|权限|auth/i.test(params.requirementDescription),
      components: ['axios'],
    },
    {
      match: (params: RecommendationParams) =>
        /图表|chart|报表/i.test(params.requirementDescription),
      components: ['echarts', '@antv/g2', 'ant-design-charts'],
    },
  ]), []);

  const recommendedComponentNames = useMemo(() => {
    const set = new Set<string>();
    recommendationRules.forEach(rule => {
      if (rule.match(recommendationParams)) {
        rule.components.forEach(componentName => set.add(componentName));
      }
    });
    return Array.from(set);
  }, [recommendationParams, recommendationRules]);

  const availableComponentMap = useMemo(() => {
    const map = new Map<string, BaseComponent>();
    baseComponents.forEach(component => {
      map.set(component.name, component);
    });
    return map;
  }, [baseComponents]);

  const filteredRecommendedComponents = useMemo(
    () => recommendedComponentNames.filter(name => {
      const definition = availableComponentMap.get(name);
      return definition && !requiredComponentNames.includes(definition.name);
    }),
    [recommendedComponentNames, availableComponentMap, requiredComponentNames]
  );

  const recommendedKey = useMemo(
    () => filteredRecommendedComponents.slice().sort().join('|'),
    [filteredRecommendedComponents]
  );

  // 根据 baseComponents 生成选项数组
  const componentOptions = baseComponents.map((component) => {
    const isRequired = requiredComponentNames.includes(component.name);
    const isRecommended = filteredRecommendedComponents.includes(component.name);
    return {
      label: (
        <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
          <span style={{ fontWeight: 500 }}>{component.name}</span>
          {isRequired && (
            <Tag color="red" style={{ fontSize: 12, lineHeight: '18px', padding: '0 8px' }}>
              必需
            </Tag>
          )}
          {!isRequired && isRecommended && (
            <Tag color="blue" style={{ fontSize: 12, lineHeight: '18px', padding: '0 8px' }}>
              推荐
            </Tag>
          )}
          <span style={{ color: '#6b7280', fontSize: '12px' }}>- {component.description || '暂无描述'}</span>
        </div>
      ),
      value: component.name,
      disabled: isRequired,
    };
  });
  // 当后端返回新的 baseComponents 列表时，自动把必需组件标记为已选
  useEffect(() => {
    if (!form) return;

    const currentSelection = form.getFieldValue('baseComponents') || [];
  const merged = new Set<string>(currentSelection);
    requiredComponentNames.forEach(name => merged.add(name));
    form.setFieldValue('baseComponents', Array.from(merged));
  }, [form, requiredComponentNames]);

  useEffect(() => {
    if (!form || filteredRecommendedComponents.length === 0 || recommendationNotified) return;

    const currentSelection: string[] = form.getFieldValue('baseComponents') || [];
    const hasOptionalSelection = currentSelection.some(name => !requiredComponentNames.includes(name));

    if (!hasOptionalSelection) {
  const merged = new Set<string>(currentSelection);
      filteredRecommendedComponents.forEach(name => merged.add(name));
      form.setFieldValue('baseComponents', Array.from(merged));
      notification.info({
        message: '已根据项目配置推荐基础组件',
        description: '我们为您预选了与当前技术栈匹配的基础组件，您可以按需调整。',
        placement: 'topRight',
        duration: 3,
      });
      setRecommendationNotified(true);
    }
  }, [filteredRecommendedComponents, form, requiredComponentNames, recommendationNotified]);

  useEffect(() => {
    setRecommendationNotified(false);
  }, [recommendedKey]);

  useEffect(() => {
    setRecommendationNotified(false);
  }, [recommendationParams]);

  // 监听组件选择变化，生成安装命令
  useEffect(() => {
    const allSelected = [...selectedBaseComponents, ...selectedExtendedComponents];
    const uniqueSelected = Array.from(new Set(allSelected));
    // 过滤掉必需组件，只显示用户主动选择的可选组件（包括基础组件中的可选部分和推荐组件）
    const optionalComponents = uniqueSelected.filter(c => !requiredComponentNames.includes(c));

    if (optionalComponents.length > 0) {
      const command = `npm install ${optionalComponents.join(' ')}`;
      setInstallCommand(command);

      if (!notified) {
        notification.success({
          message: '组件安装命令已生成',
          description: '您选择的组件的安装命令已更新，请点击"查看环境准备提示"按钮查看。',
          placement: 'topRight',
          duration: 3,
          showProgress: true,
          pauseOnHover: false,
        });
        setNotified(true);
      }
    } else {
      setInstallCommand('');
      if (notified) {
        setNotified(false);
      }
    }
  }, [selectedBaseComponents, selectedExtendedComponents, requiredComponentNames, notified]);

  // 过滤推荐组件，排除已在基础组件中存在的
  const filteredSuggested = suggested?.filter(suggestedComp => 
    !baseComponents.some(baseComp => baseComp.name === suggestedComp.name)
  ) || [];

  // 当后端给出扩展组件建议且用户尚未选择任何扩展组件时，自动预选所有建议
  useEffect(() => {
    if (!form) return;
    const currentExtended = form.getFieldValue('extendedComponents') || [];
    if (filteredSuggested.length > 0 && currentExtended.length === 0) {
      const names = filteredSuggested.map((c) => c.name);
      form.setFieldValue('extendedComponents', names);
      notification.info({
        message: '已自动选中扩展组件建议',
        description: '我们根据您的配置与需求自动勾选了推荐的扩展组件，您可以按需取消或调整。',
        placement: 'topRight',
        duration: 3,
      });
    }
  }, [filteredSuggested, form]);

  const handleCopy = (text: string) => {
    if (text) {
      navigator.clipboard.writeText(text);
      message.success('命令已复制到剪贴板');
    }
  };

  const showModal = () => {
    // 打开弹窗时动态生成最新项目创建命令
    const name = form.getFieldValue('projectName');
    const framework = form.getFieldValue('uiFramework') as FrameworkType;
    const buildTool = form.getFieldValue('buildTool');
    const language = form.getFieldValue('language');
    
    // 调试信息
    console.log('表单中的项目名称:', name);
    console.log('表单中的框架:', framework);
    console.log('表单中的构建工具:', buildTool);
    console.log('表单中的语言:', language);
    console.log('表单所有值:', form.getFieldsValue());
    
    // 根据框架、构建工具和语言组合生成命令
    let command = '';
    let officialName = '';
    
    if (framework === 'react') {
      officialName = 'React';
      if (buildTool === 'vite') {
        const template = language === 'typescript' ? 'react-ts' : 'react';
        command = `npx create-vite@latest ${name} --template ${template}`;
      } else {
        // Create React App
        if (language === 'typescript') {
          command = `npx create-react-app ${name} --template typescript`;
        } else {
          command = `npx create-react-app ${name}`;
        }
      }
    } else if (framework === 'vue') {
      officialName = 'Vue';
      if (buildTool === 'vite') {
        // Vue + Vite: 使用 create vue，它是交互式的
        command = `npm create vue@latest ${name}`;
      } else {
        // Vue CLI
        command = `npm install -g @vue/cli && vue create ${name}`;
      }
    }
    
    setSelectedCommand({ command, officialName });
    setIsModalVisible(true);
  };

  const handleOk = () => {
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  return (
    <div>
      <Title level={4}>环境准备</Title>
      <Paragraph>请先安装项目所需的 Node.js 环境，再进行后续操作。</Paragraph>

      <div style={{ marginBottom: 24 }}>
        <Button type="primary" onClick={showModal}>
          查看环境准备提示
        </Button>
      </div>

      <Modal
        title="环境准备提示"
        open={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
        footer={[
          <Button key="back" onClick={handleCancel}>
            关闭
          </Button>,
        ]}
      >
        <Typography>
          <Paragraph>
            确保您的开发环境中已安装 <Text strong>Node.js</Text> (推荐LTS版本)。
          </Paragraph>
          {selectedCommand && (
            <Paragraph>
              您选择的前端框架是 <Text strong>{selectedCommand.officialName}</Text>。创建项目的典型命令如下 (请根据实际情况调整):
                <br />
                <Text code>{selectedCommand.command}</Text>
                <Button 
                  icon={<CopyOutlined />} 
                  onClick={() => handleCopy(selectedCommand.command)} 
                  size="small"
                  style={{ marginLeft: 8 }}
                />
            </Paragraph>
          )}
          {installCommand && (
            <Paragraph>
              根据您的选择，安装附加组件的推荐命令如下:
              <br />
              <Text code>{installCommand}</Text>
              <Button 
                icon={<CopyOutlined />} 
                onClick={() => handleCopy(installCommand)} 
                size="small"
                style={{ marginLeft: 8 }}
              />
            </Paragraph>
          )}
        </Typography>
      </Modal>

      <div>
        <Form.Item
          name="baseComponents"
          label="基础组件"
          tooltip="项目创建时将自动包含以下基础组件。必需组件已默认选中且无法修改。"
        >
          <Checkbox.Group options={componentOptions} />
        </Form.Item>

        <Form.Item
          name="extendedComponents"
          label="扩展组件（建议）"
          tooltip="后端将分析需求并推荐可能需要的扩展组件，您可以选择是否包含"
        >
          {filteredSuggested.length === 0 && (
            <div style={{ color: '#6b7280', fontSize: '12px' }}>
              在第二步输入需求描述后会显示推荐组件
            </div>
          )}
          {filteredSuggested.length > 0 && (
            <Checkbox.Group 
              options={filteredSuggested.map(comp => ({
                label: (
                  <div>
                    <div style={{ fontWeight: 500, fontSize: '14px' }}>{comp.name}</div>
                    <div style={{ color: '#6b7280', fontSize: '12px' }}>{comp.description}</div>
                  </div>
                ),
                value: comp.name
              }))}
            />
          )}
        </Form.Item>
      </div>
    </div>
  );
};

export default ComponentsSelectionStep;
